import 'package:flutter/material.dart';
import 'package:math_keyboard/src/foundation/keyboard_button.dart';

import 'node.dart';

/// Class representing a button configuration for matrix input.
class MatrixButtonConfig extends KeyboardButtonConfig {
  /// Constructs a [MatrixButtonConfig].
  const MatrixButtonConfig({
    required this.label,
    this.onTap,
    int? flex,
  }) : super(flex: flex);

  /// The label of the button.
  final String label;

  /// Callback function when the button is tapped.
  final VoidCallback? onTap;
}

/// Class representing a button configuration for special function input.
class SpecialFunctionButtonConfig extends KeyboardButtonConfig {
  /// Constructs a [SpecialFunctionButtonConfig].
  const SpecialFunctionButtonConfig({
    required this.label,
    required this.functionType,
    this.asTex = false,
    this.highlighted = false,
    List<String> keyboardCharacters = const [],
    int? flex,
  }) : super(
          flex: flex,
          keyboardCharacters: keyboardCharacters,
        );

  /// The label of the button.
  final String label;

  /// The type of special function.
  final SpecialFunctionType functionType;

  /// Whether to display the label as TeX or as plain text.
  final bool asTex;

  /// The highlight level of this button.
  final bool highlighted;
}

/// Types of special functions.
enum SpecialFunctionType {
  // subscript,
  // superscript,
  integral,
  sum,
  product,
  limit,
  underset,
  overset,
  gradient,
  partial,
  infinity,
  matrix,
}

/// Extended keyboard layout for advanced mathematical symbols.
final advancedKeyboard = [
  [
    // First row: Subscript, Superscript, and basic symbols
    const BasicKeyboardButtonConfig(
      label: r'\Box_{\Box}',
      value: '_',
      args: [TeXArg.braces],
      asTex: true,
      keyboardCharacters: [
        '_',
        // This is a workaround for keyboard layout that use ^ as a toggle key.
        // In that case, "Dead" is reported as the character (e.g. for German
        // keyboards).
        'Dead',
      ],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\Box^{\Box}',
      value: '^',
      args: [TeXArg.braces],
      asTex: true,
      keyboardCharacters: [
        '^',
        // This is a workaround for keyboard layout that use ^ as a toggle key.
        // In that case, "Dead" is reported as the character (e.g. for German
        // keyboards).
        'Dead',
      ],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\nabla',
      value: r'\nabla',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\partial',
      value: r'\partial',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\infty',
      value: r'\infty',
      asTex: true,
    ),
  ],
  [
    // Second row: Integrals and sums
    const SpecialFunctionButtonConfig(
      label: r'\int_{\Box}^{\Box}',
      functionType: SpecialFunctionType.integral,
      asTex: true,
      keyboardCharacters: ['i'],
    ),
    const SpecialFunctionButtonConfig(
      label: r'\sum_{\Box}^{\Box}',
      functionType: SpecialFunctionType.sum,
      asTex: true,
      keyboardCharacters: ['s'],
    ),
    const SpecialFunctionButtonConfig(
      label: r'\prod_{\Box}^{\Box}',
      functionType: SpecialFunctionType.product,
      asTex: true,
      keyboardCharacters: ['p'],
    ),
    const SpecialFunctionButtonConfig(
      label: r'\lim_{\Box}',
      functionType: SpecialFunctionType.limit,
      asTex: true,
      keyboardCharacters: ['l'],
    ),
  ],
  [
    // Third row: Special structures
    const SpecialFunctionButtonConfig(
      label: r'\underset{\Box}{\Box}',
      functionType: SpecialFunctionType.underset,
      asTex: true,
    ),
    const SpecialFunctionButtonConfig(
      label: r'\overset{\Box}{\Box}',
      functionType: SpecialFunctionType.overset,
      asTex: true,
    ),
    // const MatrixButtonConfig(
    //   label: 'Matrix',
    //   flex: 2,
    // ), // TODO: Matrix
  ],
  [
    // Fourth row: Relations and operations
    const BasicKeyboardButtonConfig(
      label: r'\neq',
      value: r'\neq',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\leq',
      value: r'\leq',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\geq',
      value: r'\geq',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\approx',
      value: r'\approx',
      asTex: true,
    ),
    //
    const BasicKeyboardButtonConfig(
      label: r'\pm',
      value: r'\pm',
      asTex: true,
    ),
    // 等于号
    const BasicKeyboardButtonConfig(
      label: '=',
      value: '=',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\cong',
      value: r'\cong',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\equiv',
      value: r'\equiv',
      asTex: true,
    ),
  ],
  [
    // Fifth row: Navigation and control
    const PageButtonConfig(flex: 2),
    PreviousButtonConfig(),
    NextButtonConfig(),
    DeleteButtonConfig(),
  ],
];

/// Greek letters keyboard layout.
final greekKeyboard = [
  [
    // First row: Common lowercase Greek letters
    const BasicKeyboardButtonConfig(
      label: r'\alpha',
      value: r'\alpha',
      asTex: true,
      keyboardCharacters: ['a'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\beta',
      value: r'\beta',
      asTex: true,
      keyboardCharacters: ['b'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\gamma',
      value: r'\gamma',
      asTex: true,
      keyboardCharacters: ['g'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\delta',
      value: r'\delta',
      asTex: true,
      keyboardCharacters: ['d'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\epsilon',
      value: r'\epsilon',
      asTex: true,
      keyboardCharacters: ['e'],
    ),
  ],
  [
    // Second row: More lowercase Greek letters
    const BasicKeyboardButtonConfig(
      label: r'\theta',
      value: r'\theta',
      asTex: true,
      keyboardCharacters: ['t'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\lambda',
      value: r'\lambda',
      asTex: true,
      keyboardCharacters: ['l'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\mu',
      value: r'\mu',
      asTex: true,
      keyboardCharacters: ['m'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\pi',
      value: r'{\pi}',
      asTex: true,
      keyboardCharacters: ['p'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\sigma',
      value: r'\sigma',
      asTex: true,
      keyboardCharacters: ['s'],
    ),
  ],
  [
    // Third row: More Greek letters
    const BasicKeyboardButtonConfig(
      label: r'\tau',
      value: r'\tau',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\phi',
      value: r'\phi',
      asTex: true,
      keyboardCharacters: ['f'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\chi',
      value: r'\chi',
      asTex: true,
      keyboardCharacters: ['c'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\psi',
      value: r'\psi',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\omega',
      value: r'\omega',
      asTex: true,
      keyboardCharacters: ['w'],
    ),
  ],
  [
    // Fourth row: Uppercase Greek letters
    const BasicKeyboardButtonConfig(
      label: r'\Gamma',
      value: r'\Gamma',
      asTex: true,
      keyboardCharacters: ['G'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\Delta',
      value: r'\Delta',
      asTex: true,
      keyboardCharacters: ['D'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\Theta',
      value: r'\Theta',
      asTex: true,
      keyboardCharacters: ['T'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\Lambda',
      value: r'\Lambda',
      asTex: true,
      keyboardCharacters: ['L'],
    ),
    const BasicKeyboardButtonConfig(
      label: r'\Omega',
      value: r'\Omega',
      asTex: true,
      keyboardCharacters: ['W'],
    ),
  ],
  [
    // Fifth row: Navigation and control
    const PageButtonConfig(flex: 2),
    PreviousButtonConfig(),
    NextButtonConfig(),
    DeleteButtonConfig(),
  ],
];

/// Arrows and relations keyboard layout.
final arrowsKeyboard = [
  [
    // First row: Basic arrows
    const BasicKeyboardButtonConfig(
      label: r'\leftarrow',
      value: r'\leftarrow',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\rightarrow',
      value: r'\rightarrow',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\leftrightarrow',
      value: r'\leftrightarrow',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\uparrow',
      value: r'\uparrow',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\downarrow',
      value: r'\downarrow',
      asTex: true,
    ),
  ],
  [
    // Second row: Double arrows
    const BasicKeyboardButtonConfig(
      label: r'\Leftarrow',
      value: r'\Leftarrow',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\Rightarrow',
      value: r'\Rightarrow',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\Leftrightarrow',
      value: r'\Leftrightarrow',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\Uparrow',
      value: r'\Uparrow',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\Downarrow',
      value: r'\Downarrow',
      asTex: true,
    ),
  ],
  [
    // Third row: Set relations
    const BasicKeyboardButtonConfig(
      label: r'\in',
      value: r'\in',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\notin',
      value: r'\notin',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\subset',
      value: r'\subset',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\supset',
      value: r'\supset',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\subseteq',
      value: r'\subseteq',
      asTex: true,
    ),
  ],
  [
    // Fourth row: Set operations
    const BasicKeyboardButtonConfig(
      label: r'\cup',
      value: r'\cup',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\cap',
      value: r'\cap',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\setminus',
      value: r'\setminus',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\emptyset',
      value: r'\emptyset',
      asTex: true,
    ),
    const BasicKeyboardButtonConfig(
      label: r'\therefore',
      value: r'\therefore',
      asTex: true,
    ),
  ],
  [
    // Fifth row: Navigation and control
    const PageButtonConfig(flex: 2),
    PreviousButtonConfig(),
    NextButtonConfig(),
    DeleteButtonConfig(),
  ],
];

/// All available extended keyboard layouts.
// final Map<String, List<List<KeyboardButtonConfig>>> extendedKeyboardLayouts = {
//   'advanced': advancedKeyboard,
//   'greek': greekKeyboard,
//   'arrows': arrowsKeyboard,
// };
//
// /// Gets the extended keyboard layout by name.
// List<List<KeyboardButtonConfig>>? getExtendedKeyboardLayout(String name) {
//   return extendedKeyboardLayouts[name];
// }
//
// /// Gets all available extended keyboard layout names.
// List<String> getAvailableExtendedLayouts() {
//   return extendedKeyboardLayouts.keys.toList();
// }